package com.yyfax.account.service;

import com.google.common.collect.Lists;
import com.jaws.core.common.util.DateUtil;
import com.yyfax.account.common.exception.AccountExceptionCode;
import com.yyfax.account.common.util.CommonIdUtils;
import com.yyfax.account.dao.AccountFrozenDao;
import com.yyfax.account.dao.AccountTradeDao;
import com.yyfax.account.domain.AccountFlow;
import com.yyfax.account.domain.AccountFrozen;
import com.yyfax.account.domain.AccountInfo;
import com.yyfax.account.domain.AccountTrade;
import com.yyfax.account.vo.BaseTradeReq;
import com.yyfax.account.vo.FlowDataReq;

import javax.annotation.Resource;
import java.util.List;

/**
 * 账户交易抽象类
 * 
 * @author maojian
 * @date 2017-05-26 10:11:22
 * @since v1.0.0
 */
public abstract class BaseTradeService<T extends BaseTradeReq> {

	@Resource
	protected CommonIdUtils commonIdUtils;

	/**
	 * 校验数据
	 * 
	 * @author liangqm
	 * @date 2017-10-25 9:48:18
	 * @since v1.0.0
	 * @param req
	 * @return
	 */
	public abstract void checkBusiness(T req);

	/**
	 * 批量校验数据
	 *
	 * @author liangqm
	 * @date 2017-10-25 9:48:18
	 * @since v1.0.0
	 * @param req
	 * @param accountInfo
	 * @return
	 */
	public abstract void batchCheckBusiness(T req, AccountInfo accountInfo);

	/**
	 * 在途余额变更
	 * 
	 * @author maojian
	 * @date 2017-05-24 10:30:55
	 * @since v1.0.0
	 * @param req
	 * @param isBatch 是否是批量处理，批量处理不进行数据验证，批处理执行前已经完成数据校验
	 */
	public abstract void doTrade(T req, Boolean isBatch);

	/**
	 * trade Req转AccountFlowPO
	 * 
	 * @author maojian
	 * @date 2017-05-24 11:31:51
	 * @since v1.0.0
	 * @param req
	 * @return
	 */
	protected List<AccountFlow> buildAccountFlow(BaseTradeReq req) {
		List<AccountFlow> accountFlowPOLs = Lists.newArrayList();
		for (FlowDataReq flow : req.getFlowDataLs()) {
			AccountFlow accountFlow = new AccountFlow();
			accountFlow.setAccountNo(req.getAccountNo());
			accountFlow.setUserId(req.getUserId());
			accountFlow.setOutTradeNo(req.getTradeNo());
			accountFlow.setOutBusinessNo(req.getBusinessNo());
			accountFlow.setTradeAmount(flow.getTradeAmount());
			accountFlow.setFrozenAmount(flow.getFrozenAmount());
			accountFlow.setBusinessType(flow.getBusinessType());
			accountFlow.setTradeTime(flow.getTradeTime());
			accountFlow.setRemark(flow.getRemark());
			accountFlow.setCreateTime(DateUtil.getCurrentDateTime());
			accountFlowPOLs.add(accountFlow);
		}
		return accountFlowPOLs;
	}

	/**
	 * 检查account_frozen插入失败原因(冻结和失败)
	 *
	 * @author liangqm
	 * @date 2017-11-04 11:31:51
	 * @since v1.0.0
	 * @param reqAccountFrozen
	 * @param accountFrozenDao
	 * @param segment
	 * @return
	 */
	protected void checkFrozenDuplicateKeyCause(AccountFrozen reqAccountFrozen, AccountFrozenDao accountFrozenDao, String segment) {
		AccountFrozen existOrder = accountFrozenDao.queryAccountFrozenByUniqueKey(reqAccountFrozen.getTradeNo(), reqAccountFrozen.getOutTradeNo(),
				segment);
		if (existOrder == null) {// 报唯一约束冲突异常，没有查到结果，报系统异常
			throw AccountExceptionCode.SYS_ERROR.exp();
		}

		if (existOrder.getTradeNo().equals(reqAccountFrozen.getTradeNo())) {// tradeNo 自动生成，如果重复报系统异常
			throw AccountExceptionCode.AUTO_KEY_EXIST.exp(reqAccountFrozen.getTradeNo());
		}
	}

	/**
	 * 检查account_trade插入失败原因
	 *
	 * @author liangqm
	 * @date 2017-11-04 11:31:51
	 * @since v1.0.0
	 * @param rqdAccountTrade
	 * @param accountTradeDao
	 * @param segment
	 * @return
	 */
	protected void checkTradeDuplicateKeyCause(AccountTrade rqdAccountTrade, AccountTradeDao accountTradeDao, String segment) {
		AccountTrade existOrder = accountTradeDao.queryAccountTradeByUniqueKey(rqdAccountTrade.getTradeNo(), rqdAccountTrade.getOutTradeNo(),
				segment);
		if (existOrder == null) {// 报唯一约束冲突异常，没有查到结果，报系统异常
			throw AccountExceptionCode.SYS_ERROR.exp();
		}

		if (existOrder.getTradeNo().equals(rqdAccountTrade.getTradeNo())) {// tradeNo 自动生成，如果重复报系统异常
			throw AccountExceptionCode.AUTO_KEY_EXIST.exp(rqdAccountTrade.getTradeNo());
		}
	}

}
